<?php

/**
 *	\file tfcms.class.php
 *	\brief The TrueFusion CMS class
 *
 *	\mainpage TrueFusion Content Management System
 *	TFCMS is a category-based content management system written in PHP.
 *	It's main purpose is to provide a simple system for getting a website up and running without much hassle.
 *	Thanks to object-oriented programming, the core of the system is fully customizable to fit your needs.
 *	May work with PHP 5.2, but PHP 5.3.4 or higher is recommended.
 */

/*
    This file is part of TFCMS.

    TFCMS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    TFCMS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with TFCMS. If not, see <http://www.gnu.org/licenses/>.
*/

$_SERVER["DOCUMENT_ROOT"] = (isset($_SERVER["SUBDOMAIN_DOCUMENT_ROOT"]))
						  ? $_SERVER["SUBDOMAIN_DOCUMENT_ROOT"]
						  : $_SERVER["DOCUMENT_ROOT"];
define("__cwd", getcwd());
define("__root", preg_replace("~/$~", "", $_SERVER["DOCUMENT_ROOT"]));

require_once "model_tfcms.class.php";
require_once "view_tfcms.class.php";

chdir(__root);

/*!
 *	\class TFCMS
 *	\brief The TrueFusion CMS core class.
 */

class TFCMS
	{
		static protected $check_version = true;
		static protected $Model = NULL;
		static protected $View = NULL;

		/** \brief TFCMS constructor
		 *
		 *	Parameters do not require being passed in, but this method
		 *	 takes the same parameters as TFCMSView's constructor.
		 *
		 *	@see TFCMSView
		 */
		function __construct(/* $template = "Default", $default = "Default", $doctype = "XHTML 1.1", $tpl_file = "index.tpl.php" */)
			{
				if (self::$check_version)
					TFCMS::version_check();

				self::$Model = new TFCMSModel();
				if (func_num_args() > 0)
				{
					$args = func_get_args();
					self::$View = new TFCMSView($args[0], $args[1], $args[2], $args[3]);
				}

				else
					self::$View = new TFCMSView;

				self::$View->setModel(self::$Model);
			}

		/** \brief Add JavaScript scripts for every page.
		 *
		 *	@param string $script_paths A semi-colon delimited list of JavaScript file paths.
		 */
		function addGlobalJavaScripts($script_paths)
			{
				foreach (explode(";", $script_paths) as $path)
					self::$View->addJavaScript($path);
			}

		/** \brief Add meta data.
		 *
		 *	@param string $name Value for the HTML attribute, name.
		 *	@param string $content Value for the HTML attribute, content.
		 *
		 *	\warning
		 *
		 *	Currently only supports name and content attributes.
		 *	Content with the same name will get overwritten.
		 */
		function addMetaData($name, $content)
			{
				self::$View->addMetaData($name, $cotent);
			}

		/** \brief Add stylesheets for every page.
		 *
		 *	@param string $stylesheet_paths A semi-colon delimited list of stylesheet file paths.
		 */
		function addGlobalStyleSheets($stylesheet_paths)
			{
				foreach (explode(";", $stylesheet_paths) as $path)
					self::$View->addStyleSheet($path);
			}

		/** \brief Disables version checking.
		 *
		 *	Call this function for PHP versions below PHP 5.3.4.
		 */
		static function disableVersionCheck()
			{
				self::$check_version = false;
			}

		/** \brief Enable debugging messages.
		 */
		static function enableDebugging()
			{
				ini_set('display_errors', '1');
				error_reporting(E_ALL);
				define("TFCMS_DEBUG", true);
			}

		/** \brief Get the current model.
		 */
		static function getModel()
			{
				return self::$Model;
			}

		/**	\brief Get the current view.
		 */
		static function getView()
			{
				return self::$View;
			}

		/** \brief Convenience function.
		 */
		static function pathInfo()
			{
				static $path_info = NULL;
				if ($path_info === NULL)
					$path_info = str_replace($_SERVER['SCRIPT_NAME'], '', @$_SERVER['PATH_INFO']);

				return $path_info;
			}

		/** \brief Finishing piece to the puzzle.
		 *
		 *	\warning
		 *
		 *	Call this method when you have finished setting everything up.
		 *	Calling this method before any other method may prove to break things.
		 */
		function renderHtml()
			{
				self::$View->renderDocType();
				echo "<head>\n";
				$separator = (defined("TFCMS_SUB_TITLE")) ? " -- " : "";
				echo "<title>" . TFCMS_TITLE . $separator . TFCMS_SUB_TITLE . " - " . self::$View->currentPageTitle() . "</title>\n";
				self::$View->renderMetaData();
				self::$View->renderFavicon();
				self::$View->renderStyleSheet();
				self::$View->renderJavaScript();
				echo "</head>\n";
				echo "<body>\n";
				self::$View->parseTemplate();
				$curr = self::$Model->currentCategory();
				if ($curr != null)
					self::$View->renderClosingJavaScript($curr);
				echo "</body>\n";
				echo "</html>";
			}

		/** \brief Set the global favicon.
		 *
		 *	@param string $favicon Full path to favicon.
		 */
		function setFavicon($favicon)
			{
				self::$View->setFavicon($favicon);
			}

		/** Set file types for directories to consider.
		 *
		 *	@param string $file_types A semi-colon delimited string of file extensions.
		 */
		function setGlobalFileTypes($file_types)
			{
				foreach (explode(";", $file_types) as $file_type)
					self::$Model->addFileType($file_type);
			}

		/** Set the home page to \p $home_page
		 *
		 *	@param string $home_page Full path to file.
		 */
		function setHomePage($home_page)
			{
				self::$Model->setHomePage($home_page);
			}

		/** \brief Set the current model to \p $model.
		 *
		 *	\warning
		 *
		 *	Setting a new model when the previous model contains categories is not allowed.
		 *
		 *	@param TFCMSAbstractModel $model Reference to a TFCMSAbstractModel object.
		 */
		function setModel(TFCMSAbstractModel &$model)
			{
				if (count(self::$Model->getCategories()))
					throw new LogicException("Attempting to replace a model containing categories.");

				self::$Model = $model;
				self::$View->setModel($model);
			}

		/** \brief Set global site sub-title.
		 *
		 *	@param string $subtitle Sub-title for site.
		 */
		function setSiteSubTitle($subtitle)
			{
				define("TFCMS_SUB_TITLE", $subtitle);
			}

		/** \brief Set global site title.
		 *
		 *	@param string $title Title for site.
		 */
		function setSiteTitle($title)
			{
				define("TFCMS_TITLE", $title);
			}

		/** \brief Set the current view to \p $view.
		 *
		 *	@param TFCMSAbstractView $view Reference to a TFCMSAbstractView object.
		 */
		function setView(TFCMSAbstractView &$view)
			{
				self::$View = $view;
				self::$View->setModel(self::$Model);
			}

		/** \brief Convenience function.
		 *
		 *	Supported types: E_USER_WARNING, E_USER_ERROR.
		 *
		 *	@param string $message Error message to dislpay.
		 *	@param int $error_type PHP error constant.
		 */
		static function trigger_error($message, $error_type)
			{
				$debug = debug_backtrace();

				if ($error_type == E_USER_WARNING)
					$error_type = "Warning";
				else if ($error_type == E_USER_ERROR)
					$error_type = "Error";

				echo "<p class=\"backtrace\">\n<b>$error_type:</b> $message: </p>\n";
				echo "<ul class=\"backtrace\">\n";
				foreach ($debug as $key => $bt)
				{
					if (!$key)
						continue;

					$separator = (@$bt['type']) ? "::" : "";
					echo "\t<li>\n";
					echo "\t\tfrom <i><u>".@$bt['class'].$separator.$bt['function']."()</u></i> on line <b>".$bt['line']."</b> of file <b>".$bt['file']."</b>;\n";
					echo "\t</li>\n";
				}
				echo "</ul>\n\n";

				if ($error_type == "Error")
					exit();
			}

		/** \brief Version checking.
		 *
		 *	Throws a runtime exception if PHP version number is below
		 *	 the required (or recommended) PHP version.
		 */
		static function version_check()
			{
				if (!defined('PHP_VERSION_ID'))
				{
					$version = explode('.', PHP_VERSION);
					define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
				}

				if (PHP_VERSION_ID < 50304)
					throw new RuntimeException("PHP version 5.3.4 or higher is recommended for TFCMS.");
			}
	}

?>
